//
//  ExtentionsManager.m
//  CLBrowser
//
//  Created by 梁慧聪 on 2017/10/30.
//  Copyright © 2021年 梁慧聪. All rights reserved.
//

#import "CLExtentionsManager.h"
#import "CLJavaScriptHelper.h"
#import "CLUserDefaults.h"
#import "CLWebDataView.h"
#import <TFHpple/TFHpple.h>
#import "CLBook.h"
#import <YYKit/NSDictionary+YYAdd.h>
#import "CLVCNovelContent.h"

@interface CLExtentionsManager ()
@property (nonatomic, strong) NSMutableDictionary *callbacks;
@end

@implementation CLExtentionsManager
SYNTHESIZE_SINGLETON_FOR_CLASS(CLExtentionsManager);

+ (void)loadExtentionsIfNeededWhenGotTitleWithWebView:(CLWebView *)webView{
    [CLJavaScriptHelper setNoImageMode:[CLUserDefaults boolForKey:KeyNoImageModeStatus] webView:webView loadPrimaryScript:YES];
    [CLJavaScriptHelper setLongPressGestureWithWebView:webView];
//    [CLJavaScriptHelper setFindInPageWithWebView:webView];
    [CLJavaScriptHelper setTestJSBlockWithWebView:webView];
    
    NSURL *url = [NSURL URLWithString:webView.mainFURL];
    if ([CLUserDefaults boolDefaultYESForKey:KeyBlockBaiduADStatus] && ([url.host isEqualToString:@"m.baidu.com"] || [url.host isEqualToString:@"www.baidu.com"])) {
        [CLJavaScriptHelper setBaiduADBlockWithWebView:webView];
    }
}

+ (void)loadExtentionsIfNeededWhenMainFrameDidFinishLoad:(CLWebView *)webView {
}

+ (void)loadExtentionsIfNeededWhenWebViewDidChangeHtml:(CLWebView *)webView {
    NSURL *URL = webView.request.URL;
    __weak CLWebView *weakWebView = webView;
    BOOL isLoadJs = [CLJavaScriptHelper boolLoadFinish:URL.absoluteString withName:@"TestJS"];
    if (!isLoadJs) {
        return;
    }
    if ([CLUserDefaults boolForKey:CLKeyNightStatus]) {
        [CLJavaScriptHelper setEyeProtectiveWithWebView:webView colorValue:@"黑夜" loadPrimaryScript:YES];
    }
//    if ([CLUserDefaults boolForKey:KeyEyeProtectiveStatus]) {
//        NSString *theme = [CLUserDefaults stringForKey:CLKeyThemeName];
//        if (theme) {
//            [CLJavaScriptHelper setEyeProtectiveWithWebView:webView colorValue:@"黑夜" loadPrimaryScript:YES];
//        }
//    }
    if (!NULLString(URL.host)) {
        [CLJavaScriptHelper.sharedInstance.xpathInfo enumerateKeysAndObjectsUsingBlock:^(NSString * _Nonnull key, id  _Nonnull obj, BOOL * _Nonnull stop) {
            if ([key isEqualToString:URL.host]) {
                [weakWebView clWebViewDidUpdateUI];
            }
        }];
    }
    
}

+ (void)loadExtentionsIfNeededWhenWebViewDidFinishLoad:(CLWebView *)webView {
    [CLExtentionsManager loadExtentionsIfNeededWhenGotTitleWithWebView:webView];
    [self loadExtentionsIfNeededWhenWebViewDidChangeHtml:webView];
}

+ (void)evaluateScriptButNotLoadExtentionsWithWebView:(CLWebView *)webView jsKey:(NSString *)key {
    if ([key isEqualToString:KeyNoImageModeStatus]) {
        [CLJavaScriptHelper setNoImageMode:[CLUserDefaults boolForKey:KeyNoImageModeStatus] webView:webView loadPrimaryScript:NO];
    } else if ([key isEqualToString:CLKeyNightStatus]){
        if ([CLUserDefaults boolForKey:CLKeyNightStatus]) {
            [CLJavaScriptHelper setEyeProtectiveWithWebView:webView colorValue:@"黑夜" loadPrimaryScript:YES];
        }
    }
}

- (void)addCommand:(CLWebView *)webView bridge:(CLWebViewBridge *)bridge {
//    WEAK_SELF;
    /// 日志
    [bridge registerHandler:@"native_log" handler:^(id obj,  WVJBResponseCallback responseCallback) {
        JSLog(@"%@", obj);
        CLSafeExecuteBlock(responseCallback,[CLExtentionsManager responseSuccess]);
    }];
    
    /// 小说信息
    [bridge registerHandler:@"native_analyseNovelInfo" handler:^(NSString *html,  WVJBResponseCallback responseCallback) {
        JSLog(@"[native][native_analyseNovelInfo]:%ld",html.length);
        if (NULLString(html)) {
            CLSafeExecuteBlock(responseCallback,[CLExtentionsManager responseFail]);
        } else {
            CLBook *book = [[CLReadParser sharedInstance] saveToDBWithBookInfo:[NSDictionary cl_dictionaryWithJSONString:html]];
            if (NULLString(book.bookid)) return;
            if (book.catalogue.count) {
                JSLog(@"[native]最新章节:%@",book.catalogue.lastObject);
            }
            CLSafeExecuteBlock(responseCallback,[CLExtentionsManager responseSuccess]);
        }
    }];
    
    /// 小说当前章节
    [bridge registerHandler:@"native_analyseCurrentChapter" handler:^(NSString *html,  WVJBResponseCallback responseCallback) {
        JSLog(@"[native]native_analyseCurrentChapter:%ld",html.length);
        if ([CLExtentionsManager native_analyseCurrentChapter:html]) {
            CLSafeExecuteBlock(responseCallback,[CLExtentionsManager responseSuccess]);
        } else {
            CLSafeExecuteBlock(responseCallback,[CLExtentionsManager responseFail]);
        }
    }];
    
    /// 读取本地缓存
    [bridge registerHandler:@"native_getCacheBook" handler:^(NSString *sql,  WVJBResponseCallback responseCallback) {
        if (NULLString(sql)) {
            CLSafeReturnExeBlock(responseCallback,[CLExtentionsManager responseFail]);
        }
        JSLog(@"sql:%@",sql);
        NSArray<CLBook *> *books = [[CLReadParser sharedInstance] booksWithWhere:sql];
        NSMutableArray *tmp = nil;
        if (books.count) {
            tmp = [NSMutableArray array];
            for (CLBook *book in books) {
                NSMutableDictionary *p = [NSMutableDictionary dictionary];
                [p cl_setObjectSafe:book.bid forKey:@"bid"];
                [p cl_setObjectSafe:book.title forKey:@"title"];
                [p cl_setObjectSafe:book.author forKey:@"author"];
                [p cl_setObjectSafe:book.domain forKey:@"domain"];
                [p cl_setObjectSafe:book.logo forKey:@"logo"];
                [p cl_setObjectSafe:@(book.catalogue.count > 0?1:0) forKey:@"isHadCatalogue"];
                [tmp addObject:p];
            }
            CLSafeExecuteBlock(responseCallback,[CLExtentionsManager responseWithMsg:@"success" data:tmp errcode:0]);
        } else {
            CLSafeReturnExeBlock(responseCallback,[CLExtentionsManager responseFail]);
        }
    }];
    
    /// 缓存章节
    [bridge registerHandler:@"native_getCacheChapter" handler:^(NSString *sql,  WVJBResponseCallback responseCallback) {
        if (NULLString(sql)) {
            CLSafeReturnExeBlock(responseCallback,[CLExtentionsManager responseFail]);
        }
        JSLog(@"sql:%@",sql);
        NSArray<CLReadChapterModel *> *chapters = [[CLReadParser sharedInstance] chaptersWithWhere:sql];
        NSMutableArray *tmp = nil;
        if (chapters.count) {
            tmp = [NSMutableArray array];
            for (CLReadChapterModel *chapter in chapters) {
                [tmp addObject:[chapter modelToJSONObject]];
            }
            CLSafeExecuteBlock(responseCallback,[CLExtentionsManager responseWithMsg:@"success" data:tmp errcode:0]);
        } else {
            CLSafeReturnExeBlock(responseCallback,[CLExtentionsManager responseFail]);
        }
    }];
    
    /// 多来源
    [bridge registerHandler:@"navive_sources" handler:^(id data, WVJBResponseCallback responseCallback) {
        JSLog(@"%@", data);
        CLSafeReturnExeBlock(responseCallback,[CLExtentionsManager responseSuccess]);
    }];
}
+ (NSDictionary *)responseSuccess {
    return [self responseWithMsg:@"success" data:nil errcode:0];
}

+ (NSDictionary *)responseFail {
    return [self responseWithMsg:@"fail" data:nil errcode:-1];
}

+ (NSDictionary *)responseWithMsg:(NSString *)msg data:(id)data errcode:(NSInteger)errcode {
    NSMutableDictionary *res = [NSMutableDictionary dictionary];
    [res cl_setObjectSafe:msg forKey:@"msg"];
    if (data) {
        [res cl_setObjectSafe:data forKey:@"data"];
    }
    [res cl_setObjectSafe:@(errcode) forKey:@"code"];
    return res;
}

+ (BOOL)native_analyseCurrentChapter:(NSString *)html {
    JSLog(@"[native]:%ld",html.length);
    if (!NULLString(html)) {
        CLReadChapterModel *chapter = [[CLReadParser sharedInstance] saveToDBWithChapterInfo:[NSDictionary cl_dictionaryWithJSONString:html]];
        if (NULLString(chapter.chapterid)) return NO;
        JSLog(@"[native]章节内容送到app本地(KVO)：%@，%ld",chapter.chapterid,chapter.content.length);
        return YES;
    } else {
        return NO;
    }
}

- (void)webView:(CLWebView *)webView cl_novelViewOpenChapter:(CLReadChapterModel *)chapter indexPath:(NSIndexPath *)indexPath {
    NSMutableDictionary *data = [NSMutableDictionary dictionary];
    [data cl_setObjectSafe:chapter.chapterid forKey:@"chapterid"];
    [data cl_setObjectSafe:chapter.domain forKey:@"domain"];
    [data cl_setObjectSafe:chapter.title forKey:@"title"];
    [data cl_setObjectSafe:chapter.author forKey:@"author"];
    [data cl_setObjectSafe:chapter.name forKey:@"name"];
    [data cl_setObjectSafe:@(indexPath.row) forKey:@"index"];
    CLVCNovelContent *vc = [[CLVCNovelContent alloc]init];
    vc.chapter = chapter;
    CLReadChapterModel *cache = [[CLReadParser sharedInstance] chapterById:chapter.chapterid];
    if (cache && !NULLString(cache.content)) {
        chapter.content = cache.content;
        JSLog(@"[native] 读取缓存：%@",chapter.chapterid);
        [CLNavigationService pushController:vc animated:YES];
    } else {
        [webView.bridge callHandler:@"openChapter" data:data responseCallback:^(id responseData) {
            JSLog(@"[native][openChapter] %@ %@", chapter.chapterid, responseData);
            BOOL success = [responseData boolValue];
            [CLNavigationService pushController:vc animated:YES];
            if (!success) {
                [SVProgressHUD showErrorWithStatus:@"打开失败"];
            }
        }];
    }
}

- (void)webView:(CLWebView *)webView nextChapter:(BOOL)nextChapter {
    NSString *cmd = nextChapter?@"nextChapter":@"preChapter";
    [webView.bridge callHandler:cmd data:nil responseCallback:^(id responseData) {
        JSLog(@"[native][%@] %@", cmd, responseData);
    }];
}

+ (void)observeUpdateForBookid:(NSString *)bookid updateBlock:(void (^)(CLBook *book))updateBlock {
    [CLExtentionsManager.sharedInstance.callbacks cl_setObjectSafe:[updateBlock copy] forKey:bookid];
}

+ (void)observeUpdateForChapterid:(NSString *)chapterid updateBlock:(void (^)(CLReadChapterModel *chapter))updateBlock {
    [CLExtentionsManager.sharedInstance.callbacks cl_setObjectSafe:[updateBlock copy] forKey:chapterid];
}

- (NSMutableDictionary *)callbacks {
    if (!_callbacks) {
        _callbacks = [NSMutableDictionary dictionary];
    }
    return _callbacks;
}

@end
